package com.partsoft.dits.dsm;

import java.util.ArrayList;
import java.util.List;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

public class DsmSQLProviderImpl implements DsmSQLProvider {

	private final DsmOriginalSQLs info;

	public DsmSQLProviderImpl(DsmOriginalSQLs sqlInfo) {
		this.info = sqlInfo;
	}
	
	public String[] getDropMonitorLogSQLs(String monitorLogTable) {
		Assert.hasText(monitorLogTable);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		
		List<String> returnSQLs = new ArrayList<String>(info.unDeployTableSQLs.length);
		for (String returnSQL : info.unDeployTableSQLs) {
			returnSQL = returnSQL.replaceAll(K(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	public String[] getCreateMonitorLogSQLs(String monitorLogTable) {
		Assert.hasText(monitorLogTable);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		
		List<String> returnSQLs = new ArrayList<String>(info.deployTableSQLs.length);
		for (String returnSQL : info.deployTableSQLs) {
			returnSQL = returnSQL.replaceAll(K(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	private String K(String k) {
		return k.replaceAll("\\.", "\\\\.");
	}

	private String PK(String pk) {
		return KP(K(pk));
	}

	private String KP(String kp) {
		return "<" + kp + ">";
	}

	private String[] PCKs(String[] v) {
		Assert.notNull(v);
		List<String> returnList = new ArrayList<String>(v.length);
		for (String vs : v) {
			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.MonitorLogTable), KP(DsmOriginalSQLs.Constants.MonitorLogTable));
			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.MonitorLogNS), KP(DsmOriginalSQLs.Constants.MonitorLogNS));

			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.DeleteTrigger), KP(DsmOriginalSQLs.Constants.DeleteTrigger));
			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.UpdateTrigger), KP(DsmOriginalSQLs.Constants.UpdateTrigger));
			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.InsertTrigger), KP(DsmOriginalSQLs.Constants.InsertTrigger));

			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.MonitoredTable), KP(DsmOriginalSQLs.Constants.MonitoredTable));
			vs = vs.replaceAll(K(DsmOriginalSQLs.Constants.MonitoredDataId), KP(DsmOriginalSQLs.Constants.MonitoredDataId));
			returnList.add(vs);
		}
		return returnList.toArray(new String[0]);
	}

	/**
	 * 校验名称
	 * 
	 * @param table
	 * @param dataid
	 * @param trigger
	 */
	protected void validateNames(String table, String dataid, String trigger, String monitorLogTable) {
		Assert.isTrue(!monitorLogTable.toLowerCase().equals(table.toLowerCase()),
				String.format("Well be monitor table \"%s\" must not equals to \"%s\"", table, monitorLogTable));
		Assert.isTrue(!table.toLowerCase().equals(trigger.toLowerCase()),
				String.format("Well be monitor table \"%s\" must not equals to \"%s\"", table, trigger));
	}

	public String[] getCreateInsertMonitorSQLs(String table, String dataid, String trigger, String monitorLogTable, String logNS) {
		Assert.hasText(table, "must have table name");
		Assert.hasText(dataid, "must have data identity");
		Assert.hasText(trigger, "must have trigger name");
		Assert.hasText(monitorLogTable, "must have minitor log table");
		Assert.hasText(logNS, "must have monitor log namespace");
		
		table = StringUtils.trimWhitespace(table);
		dataid = StringUtils.trimWhitespace(dataid);
		trigger = StringUtils.trimWhitespace(trigger);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		logNS = StringUtils.trimWhitespace(logNS);
		
		validateNames(table, dataid, trigger, monitorLogTable);

		List<String> returnSQLs = new ArrayList<String>(info.deployTriggerInsertSQLs.length);
		for (String returnSQL : PCKs(info.deployTriggerInsertSQLs)) {
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogNS), logNS);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredDataId), dataid);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredTable), table);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.InsertTrigger), trigger);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	public String[] getCreateUpdateMonitorSQLs(String table, String dataid, String trigger, String monitorLogTable, String logNS) {

		Assert.hasText(table);
		Assert.hasText(dataid);
		Assert.hasText(trigger);
		Assert.hasText(monitorLogTable);
		Assert.hasText(logNS);
		
		table = StringUtils.trimWhitespace(table);
		dataid = StringUtils.trimWhitespace(dataid);
		trigger = StringUtils.trimWhitespace(trigger);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		logNS = StringUtils.trimWhitespace(logNS);
		
		validateNames(table, dataid, trigger, monitorLogTable);

		List<String> returnSQLs = new ArrayList<String>(info.deployTriggerUpdateSQLs.length);
		for (String returnSQL : PCKs(info.deployTriggerUpdateSQLs)) {
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogNS), logNS);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredDataId), dataid);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredTable), table);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.UpdateTrigger), trigger);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	
	}

	public String[] getCreateDeleteMonitorSQLs(String table, String dataid, String trigger, String monitorLogTable, String logNS) {
		Assert.hasText(table);
		Assert.hasText(dataid);
		Assert.hasText(trigger);
		Assert.hasText(monitorLogTable);
		Assert.hasText(logNS);
		
		table = StringUtils.trimWhitespace(table);
		dataid = StringUtils.trimWhitespace(dataid);
		trigger = StringUtils.trimWhitespace(trigger);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		logNS = StringUtils.trimWhitespace(logNS);
		
		validateNames(table, dataid, trigger, monitorLogTable);

		List<String> returnSQLs = new ArrayList<String>(info.deployTriggerDeleteSQLs.length);
		for (String returnSQL : PCKs(info.deployTriggerDeleteSQLs)) {
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogNS), logNS);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredDataId), dataid);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredTable), table);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.DeleteTrigger), trigger);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	public String[] getDropInsertMonitorSQLs(String table, String dataid, String trigger, String monitorLogTable, String logNS) {
		Assert.hasText(table);
		Assert.hasText(dataid);
		Assert.hasText(trigger);
		Assert.hasText(monitorLogTable);
		Assert.hasText(logNS);
		
		table = StringUtils.trimWhitespace(table);
		dataid = StringUtils.trimWhitespace(dataid);
		trigger = StringUtils.trimWhitespace(trigger);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		logNS = StringUtils.trimWhitespace(logNS);
		
		validateNames(table, dataid, trigger, monitorLogTable);

		List<String> returnSQLs = new ArrayList<String>(info.unDeployTriggerInsertSQLs.length);
		for (String returnSQL : PCKs(info.unDeployTriggerInsertSQLs)) {
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogNS), logNS);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredDataId), dataid);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredTable), table);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.InsertTrigger), trigger);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	public String[] getDropUpdateMonitorSQLs(String table, String dataid, String trigger, String monitorLogTable, String logNS) {
		Assert.hasText(table);
		Assert.hasText(dataid);
		Assert.hasText(trigger);
		Assert.hasText(monitorLogTable);
		Assert.hasText(logNS);
		
		table = StringUtils.trimWhitespace(table);
		dataid = StringUtils.trimWhitespace(dataid);
		trigger = StringUtils.trimWhitespace(trigger);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		logNS = StringUtils.trimWhitespace(logNS);
		
		validateNames(table, dataid, trigger, monitorLogTable);

		List<String> returnSQLs = new ArrayList<String>(info.unDeployTriggerUpdateSQLs.length);
		for (String returnSQL : PCKs(info.unDeployTriggerUpdateSQLs)) {
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogNS), logNS);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredDataId), dataid);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredTable), table);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.UpdateTrigger), trigger);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	public String[] getDropDeleteMonitorSQLs(String table, String dataid, String trigger, String monitorLogTable, String logNS) {
		Assert.hasText(table);
		Assert.hasText(dataid);
		Assert.hasText(trigger);
		Assert.hasText(monitorLogTable);
		Assert.hasText(logNS);
		
		table = StringUtils.trimWhitespace(table);
		dataid = StringUtils.trimWhitespace(dataid);
		trigger = StringUtils.trimWhitespace(trigger);
		monitorLogTable = StringUtils.trimWhitespace(monitorLogTable);
		logNS = StringUtils.trimWhitespace(logNS);
		
		validateNames(table, dataid, trigger, monitorLogTable);

		List<String> returnSQLs = new ArrayList<String>(info.unDeployTriggerDeleteSQLs.length);
		for (String returnSQL : PCKs(info.unDeployTriggerDeleteSQLs)) {
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogTable), monitorLogTable);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitorLogNS), logNS);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredDataId), dataid);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.MonitoredTable), table);
			returnSQL = returnSQL.replaceAll(PK(DsmOriginalSQLs.Constants.DeleteTrigger), trigger);
			returnSQLs.add(returnSQL);
		}
		return returnSQLs.toArray(new String[0]);
	}

	public String getConnectValidateSQL() {
		return info.connValidateSQL;
	}

	public String getReturnSchemasSQL() {
		return info.allSchemaSQL;
	}

	public String getReturnTablesSQL() {
		return info.allTableSQL;
	}

	public String getReturnTriggersSQL() {
		return info.allTriggerSQL;
	}

	public String getReturnViewsSQL() {
		return info.allViewSQL;
	}
	
}
